import { DataTypes } from 'sequelize';
import { sequelize } from '../config/database.js';

const UserLog = sequelize.define('UserLog', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true
  },
  user_id: {
    type: DataTypes.INTEGER,
    allowNull: true,
    comment: '用户ID（注册日志可能为空）'
  },
  log_type: {
    type: DataTypes.ENUM('register', 'login', 'redeem'),
    allowNull: false,
    comment: '日志类型：register-注册，login-登录，redeem-兑换码兑换'
  },
  ip_address: {
    type: DataTypes.STRING(45),
    allowNull: true,
    comment: 'IP地址'
  },
  user_agent: {
    type: DataTypes.TEXT,
    allowNull: true,
    comment: '用户代理'
  },
  extra_data: {
    type: DataTypes.JSON,
    allowNull: true,
    comment: '额外数据',
    get() {
      const value = this.getDataValue('extra_data');
      return value ? (typeof value === 'string' ? JSON.parse(value) : value) : {};
    },
    set(value) {
      this.setDataValue('extra_data', value ? JSON.stringify(value) : null);
    }
  },
  created_at: {
    type: DataTypes.DATE,
    defaultValue: DataTypes.NOW
  }
}, {
  tableName: 'user_logs',
  timestamps: false,
  indexes: [
    {
      name: 'idx_user_logs_user_id',
      fields: ['user_id'],
    },
    {
      name: 'idx_user_logs_log_type',
      fields: ['log_type'],
    },
    {
      name: 'idx_user_logs_ip_address',
      fields: ['ip_address'],
    },
    {
      name: 'idx_user_logs_created_at',
      fields: ['created_at'],
    },
  ],
});

// 实例方法
UserLog.prototype.toJSON = function() {
  const values = { ...this.get() };
  return values;
};

// 类方法
UserLog.createRegisterLog = async function(userData, ip, userAgent) {
  return await this.create({
    user_id: userData.id,
    log_type: 'register',
    ip_address: ip,
    user_agent: userAgent,
    extra_data: {
      phone: userData.phone,
      register_channel: userData.register_channel
    }
  });
};

UserLog.createLoginLog = async function(userId, ip, userAgent) {
  return await this.create({
    user_id: userId,
    log_type: 'login',
    ip_address: ip,
    user_agent: userAgent
  });
};

UserLog.createRedeemLog = async function(userId, redeemCodeId, ip, userAgent, extraData = {}) {
  return await this.create({
    user_id: userId,
    log_type: 'redeem',
    ip_address: ip,
    user_agent: userAgent,
    extra_data: {
      redeem_code_id: redeemCodeId,
      ...extraData
    }
  });
};

UserLog.getUserLogs = function(userId, options = {}) {
  const { page = 1, limit = 20, logType } = options;
  const where = { user_id: userId };
  
  if (logType) {
    where.log_type = logType;
  }
  
  return this.findAndCountAll({
    where,
    include: [
      { association: 'user', attributes: ['id', 'phone'] }
    ],
    order: [['created_at', 'DESC']],
    limit,
    offset: (page - 1) * limit
  });
};

UserLog.getLogsByType = function(logType, options = {}) {
  const { page = 1, limit = 20, startDate, endDate } = options;
  const where = { log_type: logType };
  
  if (startDate && endDate) {
    where.created_at = {
      [sequelize.Sequelize.Op.between]: [startDate, endDate]
    };
  }
  
  return this.findAndCountAll({
    where,
    include: [
      { association: 'user', attributes: ['id', 'phone'] }
    ],
    order: [['created_at', 'DESC']],
    limit,
    offset: (page - 1) * limit
  });
};

UserLog.getStatistics = async function(options = {}) {
  const { startDate, endDate } = options;
  const where = {};
  
  if (startDate && endDate) {
    where.created_at = {
      [sequelize.Sequelize.Op.between]: [startDate, endDate]
    };
  }
  
  const stats = await this.findAll({
    where,
    attributes: [
      'log_type',
      [sequelize.fn('COUNT', sequelize.col('log_type')), 'count'],
      [sequelize.fn('DATE', sequelize.col('created_at')), 'date']
    ],
    group: ['log_type', sequelize.fn('DATE', sequelize.col('created_at'))],
    order: [[sequelize.fn('DATE', sequelize.col('created_at')), 'DESC']]
  });
  
  return stats.map(stat => ({
    log_type: stat.log_type,
    count: parseInt(stat.get('count')),
    date: stat.get('date')
  }));
};

export default UserLog;
